package com.example.zz.example.datastructures;

import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 队列：
 * <p>
 * 1、在java5中新增加了java.util.Queue接口，Queue用于模拟了队列这种数据结构。Queue只有6个方法：offer、poll、peek、add、remove、element
 * 2、队列只有两个操作：队列尾部加入一个元素，队列头部移除一个元素；如果给满队列添加或空队列移除，会阻塞。先进先出(FIFO)
 * 3、Queue有两个常用的实现类：LinkedList 和 PriorityQueue。
 * 4、Dequeue 双端队列，每端可进可出；常用实现类：LinkedList、ArrayDeque、LinkedBlockingDeque
 * <p>
 * 其他java.util.concurrent包提供了其他的功能队列：
 * 非阻塞队列：ConcurrentLinkedQueue
 * 阻塞队列的4个变种：LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue、DelayQueue
 * <p>
 * 基操：
 * offer：添加一个元素并返回true， 如果队列已满，则返回false
 * poll：移除并返回队列头部元素，   如果队列是空，则返回null
 * peek：获取队列头部元素（不移除），如果队列是空，则返回null
 * <p>
 * add：添加一个元素，如果队列已满，则抛出IllegalStatementException
 * remove：移除并返回队列头部元素，如果队列是空，则抛出NoSuchElementException
 * element：返回队列头部元素（不移除），如果队列是空，则抛出NoSuchElementException
 * <p>
 * <p>
 * Dequeue 双端队列操作：
 * addFirst(Object ob):在队首增加元素
 * addLast(Object obj):在队尾增加；
 * peekFirst():查看队首；
 * peekLast:查看队尾；
 * pollFirst:移除队首；
 * pollLast:移除队尾；
 * <p>
 * <p>
 * 注意：LinkedList类实现了Queue接口，因此我们可以把LinkedList当成Queue来用。java中的LinkedList是基于双向循环链表实现的链表。
 * 为了好用，还添加了Serializable接口支持序列化，还实现了Queue等接口，可以当做栈、队列和双端队列来进行使用，所以它是一个功能集合的大杂烩。
 */
public class QueueDemo {
    public static void main(String[] args) {

        Queue<String> q = new ArrayDeque<String>();
        q.offer("");
        q.add("");

        LinkedList<String> linkedList = new LinkedList<>();
        boolean a = linkedList.offer("a");
        boolean b = linkedList.offer("b");

        System.out.println(a);
        System.out.println(b);

        System.out.println(linkedList.poll());
        System.out.println(linkedList.poll());
        System.out.println(linkedList.poll());
// 打印结果：
//        true
//        true

//        a
//        b
//        null

        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
        boolean c = queue.offer("c");
        boolean d = queue.offer("d");

        System.out.println(c);
        System.out.println(d);

        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
// 打印结果：
//        true
//        true

//        c
//        d
//        null


        //PriorityQueue保存队列元素的顺序并不是按加入队列的顺序，而是按队列元素的大小进行重新排序
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
        pq.offer(3);
        pq.offer(-6);
        pq.offer(9);
        //打印结果为[-6, 3, 9]
        System.out.println(pq);
        //打印结果为-6
        System.out.println(pq.peek());
        //打印结果为-6
        System.out.println(pq.poll());

    }
}
